﻿using Blm.Utils.Extensions;
using Language.Resource;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using VisionCloud.Core.Model.Sys;
using VisionCloud.Domain.Common;
using VisionCloud.Domain.DtoModel.Sys;
using VisionCloud.Domain.Repository.Interface.Sys;
using VisionCloud.Domain.UnitOfWork;

namespace VisionCloud.Service.Sys
{
    public class UserRoleService
    {
        public IUnitOfWork UnitOfWork { get; set; }

        public ISysUserRoleRepository SysUserRoleRepository { get; set; }

        public ISysRoleRepository SysRoleRepository { get; set; }

        /// <summary>
        /// 多语言资源类
        /// </summary>
        public IStringLocalizer<ServiceResource> ServiceLocalizer { get; set; }

        #region 用户角色

        public async Task<ApiPageResult> GetPage(SysUserRoleCondition conditon)
        {
            return await SysUserRoleRepository.GetPage(conditon);
        }

        public async Task<bool> IsAdmin(SysUserRoleDto model)
        {
            return await SysRoleRepository.AnyAsync(p => p.RoleId == model.RoleId && p.IsSuperAdministrator == true && p.IsDeleted == false);
        }

        /// <summary>
        /// 数据是否存在
        /// </summary>
        /// <param name="model"></param>
        /// <param name="isDeleted">是否检索标志为删除的</param>
        /// <returns></returns>
        public async Task<bool> Existed(SysUserRoleDto model, bool isDeleted = false)
        {
            if (isDeleted != true)
            {
                return await SysUserRoleRepository.AnyAsync(p => p.RoleId == model.RoleId && p.UserId == model.UserId && p.IsDeleted == false);
            }
            else
            {
                return await SysUserRoleRepository.AnyAsync(p => p.RoleId == model.RoleId && p.UserId == model.UserId);
            }
        }

        public async Task<bool> ExistedOtherRole(SysUserRoleDto model)
        {
            return await SysUserRoleRepository.AnyAsync(p => p.UserId == model.UserId && p.IsDeleted == false);
        }

        public async Task CreateUserRole(SysUserRoleDto model, Guid opeId)
        {
            var exists = await Existed(model);
            if (exists == true)
            {
                throw new OperationException(ServiceLocalizer["YB0334"].Value);
            }

            exists = await ExistedOtherRole(model);
            if (exists == true)
            {
                throw new OperationException(ServiceLocalizer["YB0335"].Value);
            }

            var entity = model.CopyTo<SysUserRole>();
            entity.UserRoleId = Guid.NewGuid();
            SysUserRoleRepository.Add(entity);
            await UnitOfWork.SaveChangesAsync();
        }

        public async Task DeleteUserRole(SysUserRoleDto model, Guid opeId)
        {
            var exists = await Existed(model);
            if (!exists == true)
            {
                throw new OperationException(ServiceLocalizer["YB0336"].Value);
            }
            SysUserRoleRepository.Update(t => (t.UserId == model.UserId && t.RoleId == model.RoleId && t.IsDeleted == false), d =>
                    {
                        d.IsDeleted = true;
                        d.LastUpdatedBy = opeId;
                        d.LastUpdatedDate = DateTime.Now;
                    });

            await UnitOfWork.SaveChangesAsync();
        }

        public async Task UpdateUserRole(SysUserRoleDto model, Guid opeId)
        {
            var exists = await Existed(model);
            if (!exists == true)
            {
                throw new OperationException(ServiceLocalizer["YB0336"].Value);
            }

            SysUserRoleRepository.Update(t => (t.UserId == model.UserId && t.RoleId == model.RoleId && t.IsDeleted == false), d =>
            {
                d.RoleId = model.NewRoleId;
                d.LastUpdatedBy = opeId;
                d.LastUpdatedDate = DateTime.Now;
            });
            await UnitOfWork.SaveChangesAsync();
        }

        public async Task<List<SysUserRoleDto>> FindUserRole(Guid userId)
        {
            return await SysUserRoleRepository.FindSysUserRole(userId);
        }

        /// <summary>
        /// 角色转让-现设计为角色交换
        /// </summary>
        /// <param name="fromModel"></param>
        /// <param name="toModel"></param>
        /// <param name="opeId"></param>
        /// <returns></returns>
        public async Task TransferUserRole(UserRoleTransferDto model, Guid opeId)
        {
            var fromModel = new SysUserRoleDto() { UserId = model.FromUserId, RoleId = model.FromRoleId };

            //不是管理员
            if ((await IsAdmin(fromModel)) != true)
            {
                if (!opeId.Equals(fromModel.UserId))
                {
                    throw new OperationException(ServiceLocalizer["YB0337"].Value);
                }
            }

            var exists = await Existed(fromModel);
            if (!exists == true)
            {
                throw new OperationException(ServiceLocalizer["YB0338"].Value);
            }

            var toModel = new SysUserRoleDto() { UserId = model.ToUserId, RoleId = model.ToRoleId };
            exists = await Existed(toModel);
            if (!exists == true)
            {
                throw new OperationException(ServiceLocalizer["YB0339"].Value);
            }

            //受让人如果还不是该角色，则接受该角色，否则不做操作
            var toNewModel = new SysUserRoleDto() { UserId = model.ToUserId, RoleId = model.FromRoleId };
            exists = await Existed(toNewModel, true);
            if (exists != true)//受让人还没有该角色
            {
                //throw new OperationException("操作失败:受让人的已经是该角色");
                SysUserRoleRepository.Update(t => (t.UserId == toModel.UserId && t.RoleId == toModel.RoleId), d =>
                {
                    d.RoleId = fromModel.RoleId;
                    d.LastUpdatedBy = opeId;
                    d.LastUpdatedDate = DateTime.Now;
                });
            }

            //转让人如果是受让人的角色，则不做任何操作
            var fromNewModel = new SysUserRoleDto() { UserId = model.FromUserId, RoleId = model.ToRoleId };
            exists = await Existed(fromNewModel, true);
            if (exists != true)//转让人还没有该角色
            {
                SysUserRoleRepository.Update(t => (t.UserId == fromModel.UserId && t.RoleId == fromModel.RoleId), d =>
                {
                    d.RoleId = toModel.RoleId;
                    d.LastUpdatedBy = opeId;
                    d.LastUpdatedDate = DateTime.Now;
                });
            }

            await UnitOfWork.SaveChangesAsync();
        }

        #endregion 用户角色
    }
}